package cate.game.activity.herodirectbuy;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.herodirectbuy.row.HeroDirectBuyBaseRow;
import cate.common.table.herodirectbuy.row.HeroDirectBuyPoolRow;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.herodirectbuy.msg.DirectInfoResp;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.annotation.Transient;

import java.util.*;

@Slf4j
@NoteClass("英雄直充活动")
public class HeroDirectBuyPO extends RoleActivitySingle {
    @NoteField("已充值金额(分)")
    public int payNum;

    @NoteField("已消费钻石")
    public int consumeNum;

    @NoteField("刷新剩余次数")
    public int freeTimes;

    @NoteField("直购牌组")
    public Map<Integer, HeroRewardPool> pool;

    @NoteField("上次刷新时间")
    public long lastRefreshTime;

    @NoteField("刷新间隔")
    public long interval;

    @JsonIgnore
    @NoteField("首次刷新是否已使用")
    public boolean firstOver;

    @NoteField("期数")
    public int group;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (pool == null) {
            pool = new HashMap<>();
            group = 1;
        }
        role.getActivity().registerRecharge(this, this::onPay);
    }

    /**
     * 人民币增加
     * @param pay
     */
    public void onPay(long pay) {
        if (!enable()) {
            return;
        }
        int timesOld = payNum / (getRow().payNum*100);
        payNum += pay;
        int timesNew = payNum / (getRow().payNum*100);
        addRefreshTimes(timesNew-timesOld);
    }

    /**
     * 钻石增加
     * @param consume
     */
    public void consumeAdd(long consume) {
        if (!enable()) {
            return;
        }
        int timesOld = consumeNum / (getRow().consumeNum);
        consumeNum += consume;
        int timesNew = consumeNum / (getRow().consumeNum);
        addRefreshTimes(timesNew-timesOld);
    }

    public void clear() {
        payNum = 0;
        consumeNum = 0;
        freeTimes = 0;
        pool.clear();
        lastRefreshTime = 0L;
        interval = 0L;
        firstOver = false;
    }

    @JsonIgnore
    public  HeroDirectBuyBaseRow getRow() {
        return role.getGame().table.heroDirectBuy.base.get(base.configTid);
    }

    //增加刷新次数
    private void addRefreshTimes(int count) {
        if (count > 0) {
            MixRes item = new MixRes(getRow().item);
            item.multiply(count).add(role);
        }
        noticeUpdate();
    }

    public void noticeUpdate() {
        role.sendNow(new DirectInfoResp(this));
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        clear();
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        HeroDirectBuyBaseRow config = getRow();
        if (config == null) {
            clear();
            return;
        }
        if (interval == 0) {
            interval = config.refreshAdd;
            freeTimes = config.limit;
        }
    }

    /**
     * 刷新卡组
     * @param num 数量
     */
    public GameResult<Void> refreshList(int num) {
        GameResult<Void> r = new GameResult<>();
        if (!firstOver) {
            freeTimes = getRow().limit;
        }
        //非首次一键翻牌,优先免费次数
        if (firstOver) {
            if (freeTimes > 0) {
                freeTimes --;
            } else {
                MixRes consume = new MixRes(getRow().item);
                GameResult<MixResItem> cResult = consume.consume(role);
                if (!cResult.ok()) {
                    return r.fail(cResult);
                }
            }
        }
        pool.clear();
        //首次刷新
        if (!firstOver) {
            for (HeroDirectBuyPoolRow row : role.getGame().table.heroDirectBuy.pool.getList()) {
                //首次刷新作弊
                if (row.isFirst) {
                    HeroRewardPool item = new HeroRewardPool();
                    item.changeToPool(row);
                    pool.put(row.id,item);
                }
            }
        }

        while (pool.size() < num) {
            HeroDirectBuyPoolRow row = role.getGame().table.heroDirectBuy.pool.randomPool();
            HeroRewardPool item = new HeroRewardPool();
            item.changeToPool(row);
            if (!pool.containsKey(row.id)) {
                pool.put(row.id,item);
            }
        }

        //第一次使用免费次数后记录刷新时间
        if (freeTimes == (getRow().limit - 1)) {
            lastRefreshTime = now();
        }
        firstOver = true;
        noticeUpdate();
        return r.success();
    }

    /**
     * 物品购买（钻石）
     * @param tid
     * @return
     */
    public EcResult<Void> buyItem(int tid) {
        EcResult<Void> r = new GameResult<>();
        HeroRewardPool item = pool.get(tid);
        if (!pool.containsKey(tid)) {
            return r.fail("当前无该牌面物品");
        }
        HeroDirectBuyPoolRow row = role.getGame().table.heroDirectBuy.pool.get(tid);
        if (row == null) {
            return r.fail("未找到配置");
        }
        if (item.purchase) {
            return r.fail("商品限购一次");
        }
        //消耗
        EcResult<Void> r_consume = diamondConsume(row,tid);
        if (!r_consume.ok()) {
            return r.fail(r_consume.message);
        }
        //奖励发放
        provideReward(role, tid, true);
        return r.success();
    }

    /**
     * 钻石消耗
     * @param row
     * @param tid
     * @return
     */
    private EcResult<Void> diamondConsume(HeroDirectBuyPoolRow row, int tid) {
        EcResult<Void> r = new EcResult<>();
        if (row.type != HeroDirectBuyPoolRow.TYPE_ITEM) {
            return r.fail("不支持此购买模式");
        }
        if (row.payId > 0){
            return r.fail("不支持此购买模式");
        }
        MixRes costRes = new MixRes(row.priceNow);
        if (costRes.isEmpty()) {
            return r.fail("配置消耗物品为空");
        }
        EcResult<MixResItem> r_res = costRes.consumeCheck(role, null);
        if (!r_res.ok()) {
            return r.fail(r_res.message);
        }
        role.log.setOperation(getGDOperation(), tid);
        costRes.consume(role);
        role.log.clearOperation();
        return r.success();
    }

    @Override
    public void onPaySuccess(PayItemRow payItemRow) {
        provideReward(role, payItemRow.funcSubId, true);
    }

    /**
     * 购买后发放奖励
     * @param role
     * @param tid
     * @param dialog
     */
    protected void provideReward(Role role, int tid, boolean dialog) {
        HeroDirectBuyPoolRow row = role.getGame().table.heroDirectBuy.pool.get(tid);
        if (row == null) {
            return ;
        }
        MixRes rewardRes = new MixRes(row.rewardStr);
        if (rewardRes.isEmpty()) {
            return ;
        }
        EcResult<?> exe = new MixResAdder().setRes(rewardRes)
                .setOperation(getGDOperation())
                .setOperationSub(tid)
                .setDialogReward(dialog)
                .setSendMailWhenFull(true)
                .exe(role);
        pool.get(tid).purchase = true;
        noticeUpdate();
    }

    @JsonIgnore
    @Transient
    private int getGDOperation() {
        switch (funcId()) {
            case GDFunc.HERO_DIRECT_PURCHASE:
                return GDOperation.HERO_DIRECT_PURCHASE;
        }
        return GDOperation.NULL;
    }

    public void tick() {
        if (!enable() || freeTimes == getRow().limit || lastRefreshTime == 0) {
            return;
        }
        //刷新间隔时间
        long intervalTime = now() - lastRefreshTime;
        if (intervalTime > (interval*1000) && freeTimes < getRow().limit ) {
            //定时增加免费次数
            freeTimes ++;
            lastRefreshTime = now();
            //免费次数满后刷新时间置0
            if (freeTimes == getRow().limit) {
                lastRefreshTime = 0;
            }
            noticeUpdate();
        }
    }

    /**
     * 支付条件
     * @param pir 支付配置
     * @return
     */
    @Override
    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        int tid = pir.funcSubId;
        if (!pool.containsKey(tid)) {
            return r.fail("当前无该牌面物品");
        }
        HeroDirectBuyPoolRow config = role.getGame().table.heroDirectBuy.pool.get(tid);
        if (config == null) {
            return r.fail("未找到英雄直购奖励池配置");
        }

        if (config.type != HeroDirectBuyPoolRow.TYPE_PAY) {
            return r.fail("不支持此购买模式");
        }
        if (pool.get(tid).purchase) {
            return r.fail("商品限购一次");
        }
        MixRes rewardRes = new MixRes(config.rewardStr);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        return r.success();
    }


    /**
     * 清空奖励池
     * @return
     */
    public GameResult<Void> cleanPool() {
        GameResult<Void> r = new GameResult<>();
        if (pool.isEmpty()){
            return r.fail("奖励池为空");
        }
        pool.clear();
        noticeUpdate();
        return r.success();
    }
}
